from django.shortcuts import render
from rest_framework.views import APIView
from .serializers import UserSkuCartSerializer
from django_redis import get_redis_connection
from rest_framework.response import Response
import pickle
import base64
from goods.models import SKU
from .serializers import UserSkuCartListSerializer,DeleteCartSerializer
"""
添加商品到购物车
1,前端点击加入购物车,携带商品编号,商品数量,选中状态
2,校验数据
3,判断用户的登陆状态,储存到redis或者是cookie
4,返回响应(sku_id,count,selected)

获取购物车数据
1,当前端页面,一进入到购物车页面获取
2,判断用户是否有登陆,取出对应的数据
3,转换数据返回(id,name,price,selected,default_image_url,count)

更新购物车的数据
1,当前端点击增加,减少,勾选取消勾选的时候发送请求
2,校验数据
3,判断用户是否登陆,操作redis或者,cookie中的数据
4.返回响应


"""
class UserSkuCartView(APIView):

    #为了让未登录的用户也能,访问该视图,重写方法
    def perform_authentication(self, request):
        pass

    def post(self,request):
        #1,获取前端传递的数据
        dict_data = request.data

        #2,获取序列化器校验
        serializer = UserSkuCartSerializer(data=dict_data)
        serializer.is_valid(raise_exception=True)

        #3,取出数据
        sku_id = serializer.data.get("sku_id")
        count = serializer.data.get("count")
        selected = serializer.data.get("selected")

        #4,获取用户对象
        try:
            user = request.user
        except Exception as e:
            user = None

        #5,判断用户状态
        if user and request.user.is_authenticated:
            #5,1获取redis对象
            redis_conn = get_redis_connection("cart")
            pipeline = redis_conn.pipeline()

            #5,2 存储数据到redis
            pipeline.hincrby("cart_%s"%user.id,sku_id,count)
            if selected:
                pipeline.sadd("cart_selected_%s"%user.id,sku_id)

            #5,3提交过程,如果不执行,都失败
            pipeline.execute()

            #5,4,返回响应
            return Response(serializer.data,status=201)

        #6,未登录用户,获取cookie购物车数据
        cookie_cart = request.COOKIES.get("cart")

        #7,将cookie中的数据,转成字典
        cookie_cart_dict = {}
        if cookie_cart:
            cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart))

        #8,将提交的商品编号,数量,选中状态添加到字典中
        if sku_id in cookie_cart_dict:
            count += cookie_cart_dict[sku_id]["count"]

        cookie_cart_dict[sku_id] = {
            "count":count,
            "selected":selected
        }

        #9,将字典数据,转成字符串,写到cookie中,返回响应
        response = Response(serializer.data,status=201)
        cookie_cart = base64.b64encode(pickle.dumps(cookie_cart_dict)).decode()
        response.set_cookie("cart",cookie_cart)
        return response

    def get(self,request):
        #1,获取用户
        try:
            user = self.request.user
        except Exception as e:
            user = None

        #2,判断用户是否登陆
        if user and request.user.is_authenticated:
            #2,1获取redis对象
            redis_conn = get_redis_connection("cart")

            #2,3取出redis数据,商品数据,选中状态数据
            redis_cart_dict = redis_conn.hgetall("cart_%s"%user.id)
            redis_cart_selected = redis_conn.smembers("cart_selected_%s"%user.id)

            #2,4转换数据为对应的格式返回
            sku_list = []
            for sku_id,count in redis_cart_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku.count = count
                sku.selected = sku_id in redis_cart_selected
                sku_list.append(sku)
            #2,5,获取序列化器,转换数据,返回响应
            serializer = UserSkuCartListSerializer(instance=sku_list,many=True)
            return Response(serializer.data)

        #3,获取未登录用户数据
        cookie_cart = request.COOKIES.get("cart")

        #4,判断cookie是否有数据
        if not cookie_cart:
            return Response(status=200)

        #5,将cookie数据,解密成字典
        cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart))

        #6,遍历字典,转换sku对象,添加到列表中
        sku_list = []
        for sku_id, count_selected in cookie_cart_dict.items():
            sku = SKU.objects.get(id=sku_id)
            sku.count = count_selected["count"]
            sku.selected = count_selected["selected"]
            sku_list.append(sku)

        #,获取序列化器,转换数据返回
        serializer = UserSkuCartListSerializer(instance=sku_list,many=True)
        return Response(serializer.data,status=200)

    def put(self,request):
        #1,获取提交的数据
        dict_data = request.data

        #2,获取序列化器校验数据
        serializer = UserSkuCartSerializer(data=dict_data)
        serializer.is_valid(raise_exception=True)

        #3,获取携带的数据
        sku_id = serializer.data.get("sku_id")
        count = serializer.data.get("count")
        selected = serializer.data.get("selected")

        #4,获取用户对象
        try:
            user = request.user
        except Exception as e:
            user = None

        #5,判断用户是否登陆了
        if user and request.user.is_authenticated:
            #5,1 获取redis对象
            redis_conn = get_redis_connection("cart")

            #5,2, 设置提交的数据到redis
            redis_conn.hset("cart_%s"%user.id,sku_id,count)
            if selected:
                redis_conn.sadd("cart_selected_%s"%user.id,sku_id)
            else:
                redis_conn.srem("cart_selected_%s" % user.id, sku_id)

            #5,3返回响应
            return Response(serializer.data,status=200)

        #6,用户未登录,获取cookie数据
        cookie_cart = request.COOKIES.get("cart")

        #7,将cookie数据,转成字典
        cookie_cart_dict = {}
        if cookie_cart:
            cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart))

        #8,更新数据
        if sku_id in cookie_cart_dict:
            cookie_cart_dict[sku_id]["count"] = count
            cookie_cart_dict[sku_id]["selected"] = selected

        #9,转换数据返回响应
        cookie_cart = base64.b64encode(pickle.dumps(cookie_cart_dict)).decode()
        response = Response(serializer.data)
        response.set_cookie("cart",cookie_cart,300)
        return response

    def delete(self,request):
        #1,获取商品sku_id
        dict_data = request.data

        #2,获取序列化器校验编号
        serializer = DeleteCartSerializer(data=dict_data)
        serializer.is_valid(raise_exception=True)

        #3,获取数据
        sku_id = serializer.data.get("sku_id")

        #4,获取用户对象
        try:
            user = request.user
        except Exception as e:
            user = None

        #5,判断用户对象是否存在
        if user and request.user.is_authenticated:
            #6,获取redis对象,删除数据
            redis_conn = get_redis_connection("cart")
            redis_conn.hdel("cart_%s"%user.id,sku_id)
            redis_conn.srem("cart_selected_%s"%user.id,sku_id)

            #7,返回响应
            return Response(serializer.data,status=204)

        #6,未登录用户,购物车数据删除
        cookie_cart = request.COOKIES.get("cart")
        if not cookie_cart:
            return Response(status=204)

        #7,将cookie数据,转成字典
        cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart))

        #8,判断sku_id是否在字典中
        if sku_id in cookie_cart_dict:
            del cookie_cart_dict[sku_id]

        #9,将字典数据,转换成字符串返回响应
        cookie_cart = base64.b64encode(pickle.dumps(cookie_cart_dict)).decode()
        response = Response(serializer.data,status=204)
        response.set_cookie("cart",cookie_cart)
        return response

